}
/// Get the metadata for a target in a specific profile
+ /// We build to the path: "{filename}-{target_metadata}"
+ /// We use a linking step to link/copy to a predictable filename
+ /// like `target/debug/libfoo.{a,so,rlib}` and such.
pub fn target_metadata(&self, unit: &Unit) -> Option<Metadata> {
// No metadata for dylibs because of a couple issues
// - OSX encodes the dylib name in the executable
// - Windows rustc multiple files of which we can't easily link all of them
- if !unit.profile.test && unit.target.is_dylib() {
+ //
+ // Two expeptions
+ // 1) Upstream dependencies (we aren't exporting + need to resolve name conflict)
+ // 2) __CARGO_DEFAULT_LIB_METADATA env var
+ //
+ // Note, though, that the compiler's build system at least wants
+ // path dependencies (eg libstd) to have hashes in filenames. To account for
+ // that we have an extra hack here which reads the
+ // `__CARGO_DEFAULT_METADATA` environment variable and creates a
+ // hash in the filename if that's present.
+ //
+ // This environment variable should not be relied on! It's
+ // just here for rustbuild. We need a more principled method
+ // doing this eventually.
+ if !unit.profile.test &&
+ unit.target.is_dylib() &&
+ unit.pkg.package_id().source_id().is_path() &&
+ !env::var("__CARGO_DEFAULT_LIB_METADATA").is_ok() {
return None;
}
.unwrap();
assert_that(&p.bin("foo"), existing_file());
+ assert_that(&p.bin("libbar.rlib"), is_not(existing_file()));
+ assert_that(&p.bin("libbaz.rlib"), is_not(existing_file()));
assert_that(
process(&p.bin("foo")),
.unwrap();
assert_that(&p.bin("foo"), existing_file());
+ assert_that(&p.bin("libbar.rlib"), is_not(existing_file()));
+ assert_that(&p.bin("libbaz.rlib"), is_not(existing_file()));
assert_that(
process(&p.bin("foo")),
.unwrap();
assert_that(&p.bin("foo"), existing_file());
+ assert_that(&p.bin("libbar.rlib"), is_not(existing_file()));
+ assert_that(&p.bin("libbaz.rlib"), is_not(existing_file()));
assert_that(
process(&p.bin("foo")),
assert_that(p.cargo_process("build"), execs());
assert_that(&p.bin("foo"), existing_file());
+ assert_that(&p.bin("libbar.rlib"), is_not(existing_file()));
+ assert_that(&p.bin("libbaz.rlib"), is_not(existing_file()));
assert_that(process(&p.bin("foo")),
execs().with_stdout("test passed\n"));
execs().with_status(0));
}
+#[test]
+fn cargo_default_env_metadata_env_var() {
+ // Ensure that path dep + dylib + env_var get metadata
+ // (even though path_dep + dylib should not)
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "bar"
+ "#)
+ .file("src/lib.rs", "// hi")
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "bar"
+ crate_type = ["dylib"]
+ "#)
+ .file("bar/src/lib.rs", "// hello");
+
+ // No metadata on libbar since it's a dylib path dependency
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(0).with_stderr(&format!("\
+[COMPILING] bar v0.0.1 ({url}[/]bar)
+[RUNNING] `rustc bar[/]src[/]lib.rs --crate-name bar --crate-type dylib \
+ -C prefer-dynamic -g \
+ -C metadata=[..] \
+ --out-dir [..] \
+ --emit=dep-info,link \
+ -L dependency={dir}[/]target[/]debug[/]deps`
+[COMPILING] foo v0.0.1 ({url})
+[RUNNING] `rustc src[/]lib.rs --crate-name foo --crate-type lib -g \
+ -C metadata=[..] \
+ -C extra-filename=[..] \
+ --out-dir [..] \
+ --emit=dep-info,link \
+ -L dependency={dir}[/]target[/]debug[/]deps \
+ --extern bar={dir}[/]target[/]debug[/]deps[/]libbar.dylib`
+[FINISHED] debug [unoptimized + debuginfo] target(s) in [..]
+",
+dir = p.root().display(),
+url = p.url(),
+)));
+
+ assert_that(p.cargo_process("clean"), execs().with_status(0));
+
+ // If you set the env-var, then we expect metadata on libbar
+ assert_that(p.cargo_process("build").arg("-v").env("__CARGO_DEFAULT_LIB_METADATA", "1"),
+ execs().with_status(0).with_stderr(&format!("\
+[COMPILING] bar v0.0.1 ({url}[/]bar)
+[RUNNING] `rustc bar[/]src[/]lib.rs --crate-name bar --crate-type dylib \
+ -C prefer-dynamic -g \
+ -C metadata=[..] \
+ --out-dir [..] \
+ --emit=dep-info,link \
+ -L dependency={dir}[/]target[/]debug[/]deps`
+[COMPILING] foo v0.0.1 ({url})
+[RUNNING] `rustc src[/]lib.rs --crate-name foo --crate-type lib -g \
+ -C metadata=[..] \
+ -C extra-filename=[..] \
+ --out-dir [..] \
+ --emit=dep-info,link \
+ -L dependency={dir}[/]target[/]debug[/]deps \
+ --extern bar={dir}[/]target[/]debug[/]deps[/]libbar-[..].dylib`
+[FINISHED] debug [unoptimized + debuginfo] target(s) in [..]
+",
+dir = p.root().display(),
+url = p.url(),
+)));
+}
+
#[test]
fn crate_env_vars() {
let p = project("foo")